/**
 * 版权所有@北京博创联动科技有限公司。未经许可，不得擅自复制、传播
 */
package com.uptech.homer.util;

import com.uptech.homer.beans.AlarmInfo;
import com.uptech.homer.beans.CanInfo;
import com.uptech.homer.beans.CanInfo.Group;
import com.uptech.homer.beans.annotation.AlarmField;
import com.uptech.homer.beans.annotation.CANField;
import com.uptech.homer.itf.ICanInfo;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 为CAN信息解析提供便捷工具类
 *
 * @author lei
 */
public class CanInfoUtil {

    /**
     * 通过遍历对象中标注了CanField注解的方法，自动创建Can信息Map
     *
     * @param canInfoObj
     *
     * @return
     */
    public static List<Group> getCanInfo(ICanInfo canInfoObj) {

        List<Group> canInfoList = new ArrayList<Group>();
        TreeMap<String, Group> canInfoGroupMap = new TreeMap<String, Group>(new SortChinese());

        if (canInfoObj != null) {

            Method[] methods = canInfoObj.getClass().getDeclaredMethods();
            if (methods != null && methods.length > 0) {

                for (Method method : methods) {

                    // 遍历所有“getXXX”方法
                    if (method.getName().startsWith("get")) {

                        // 如果当前方法标注了CANField
                        if (method.getAnnotation(CANField.class) != null) {
                            CANField cANField = method.getAnnotation(CANField.class);

                            if (!canInfoGroupMap.containsKey(cANField.group())) {
                                CanInfo.Group group = new CanInfo.Group(cANField.group());

                                canInfoGroupMap.put(group.getName(), group);
                            }

                            CanInfo.Group group = canInfoGroupMap.get(cANField.group());

                            try {

                                String value = "";
                                if ("99999".equals(method.invoke(canInfoObj).toString())) {
                                    value = "NC";
                                } else {
                                    value = cANField.prefix() + method.invoke(canInfoObj) + cANField.suffix();
                                }
                                group.addChild(new CanInfo(cANField.name(), value));
                            } catch (Throwable e) {
                                group.addChild(new CanInfo(cANField.name(), cANField.prefix() + cANField.suffix()));
                            }
                        }
                    }
                }
            }
        }

        if (canInfoGroupMap != null && canInfoGroupMap.size() > 0) {

            canInfoList.addAll(canInfoGroupMap.values());

            // 对children做单独排序
            for (Group g : canInfoList) {
                Collections.sort(g.getChildren(), new ComparatorSerializable<CanInfo>());
            }

        }

        return canInfoList;
    }

    /**
     * 通过遍历对象中标注了AlarmField注解的方法，自动创建报警信息Map
     *
     * @param canInfoObj
     *
     * @return
     */
    public static List<Group> getAlarmInfo(ICanInfo canInfoObj) {

        List<Group> alarmInfoList = new ArrayList<Group>();
        Map<String, Group> alarmInfoGroupMap = new HashMap<String, Group>();

        if (canInfoObj != null) {

            Method[] methods = canInfoObj.getClass().getDeclaredMethods();
            if (methods != null && methods.length > 0) {

                for (Method method : methods) {

                    // 遍历所有“getXXX”方法
                    if (method.getName().startsWith("get")) {

                        // 如果当前方法标注了AlarmField
                        if (method.getAnnotation(AlarmField.class) != null) {
                            AlarmField alarmField = method.getAnnotation(AlarmField.class);

                            if (!alarmInfoGroupMap.containsKey(alarmField.group())) {
                                CanInfo.Group group = new CanInfo.Group(alarmField.group());

                                alarmInfoGroupMap.put(group.getName(), group);
                                alarmInfoList.add(group);
                            }

                            CanInfo.Group group = alarmInfoGroupMap.get(alarmField.group());

                            Object alarmInfoObj = null;
                            try {
                                alarmInfoObj = method.invoke(canInfoObj);
                            } catch (Throwable e) {
                            }

                            if (alarmInfoObj != null && AlarmInfo.class.isAssignableFrom(alarmInfoObj.getClass())) {
                                group.addChild((AlarmInfo) alarmInfoObj);
                            }
                        }
                    }
                }
            }
        }

        return alarmInfoList;
    }
}
